package com.agentai.framework.util;


import com.alibaba.fastjson.JSON;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * @author by fuzhilin
 * @Classname ScopeUtils
 * @Description TODO
 * @Date 2023/4/4 11:39
 */
public class ScopeUtils {

	/**
	 * 赤道半径 公里
	 */
	private static double EARTH_RADIUS = 6371.393D;

	/**
	 * 根据中心点坐标和方圆距离返回最大最小值坐标
	 * @param longitude
	 * @param latitude
	 * @param raidus
	 * @return
	 */
	public static double[] getScope(double longitude, double latitude, double raidus) {
		//先计算查询点的经纬度范围
		double PI = 3.1415926535897931D;
        /*double EARTH_RADIUS = 6378137;
        double RAD = Math.PI / 180.0;*/

		Double degree = (24901 * 1609) / 360.0;
		double raidusMile = raidus * 1000;

		Double dpmLat = 1 / degree;
		Double radiusLat = dpmLat * raidusMile;
		Double minLat = latitude - radiusLat;
		Double maxLat = latitude + radiusLat;

		Double mpdLng = degree * Math.cos(latitude * (PI / 180));
		Double dpmLng = 1 / mpdLng;
		Double radiusLng = dpmLng * raidusMile;
		Double minLng = longitude - radiusLng;
		Double maxLng = longitude + radiusLng;

		return new double[]{minLat, maxLat, minLng, maxLng};
	}

	public static double[] getScopes(RepairStoreDto repairStoreDto) {
		//先计算查询点的经纬度范围
		//地球半径千米
		double r = 6371;
		//0.5千米距离
		double dis = 0.5;
		double dlng = 2 * Math.asin(Math.sin(dis / (2 * r)) / Math.cos(repairStoreDto.getLat() * Math.PI / 180));
		dlng = dlng * 180 / Math.PI;//角度转为弧度
		double dlat = dis / r;
		dlat = dlat * 180 / Math.PI;
		double minlat = repairStoreDto.getLat() - dlat;
		double maxlat = repairStoreDto.getLat() + dlat;
		double minlng = repairStoreDto.getLon() - dlng;
		double maxlng = repairStoreDto.getLon() + dlng;
//      Object[] valuess = {minlng,maxlng,minlat,maxlat};
		return new double[]{minlng, maxlng, minlat, maxlat};
	}


	class RepairStoreDto{
		private double lat;
		private double lon;

		public double getLat() {
			return lat;
		}

		public void setLat(double lat) {
			this.lat = lat;
		}

		public double getLon() {
			return lon;
		}

		public void setLon(double lon) {
			this.lon = lon;
		}
	}


	private static double rad(double d) {
		return (d * 3.1415926535897931D) / 180D;
	}

	/**
	 * 根据两点间经纬度坐标（double值），计算两点间距离，单位为KM
	 * @param lng1
	 * @param lat1
	 * @param lng2
	 * @param lat2
	 * @return
	 */
	public static double distanceKM(double lng1, double lat1, double lng2,
									 double lat2) {
		double radLat1 = rad(lat1);
		double radLat2 = rad(lat2);
		double a = radLat1 - radLat2;// a 是两坐标点的纬度之差
		double b = rad(lng1) - rad(lng2);// b 是两坐标点的经度之差
		double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
				+ Math.cos(radLat1) * Math.cos(radLat2)
				* Math.pow(Math.sin(b / 2), 2)));
		s = s * EARTH_RADIUS;//地球半径
		BigDecimal bigDecimal = new BigDecimal(s).setScale(2, RoundingMode.HALF_UP);

		return bigDecimal.doubleValue();
	}
	/**
	 * 返回距离为公里
	 * @param lat1
	 * @param lng1
	 * @param lat2
	 * @param lng2
	 * @return
	 */
	public static double getDistance(double lat1, double lng1, double lat2, double lng2) {
		double radLat1 = rad(lat1);
		double radLat2 = rad(lat2);
		double a = radLat1 - radLat2;
		double b = rad(lng1) - rad(lng2);
		double s = 2D * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2D), 2D) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2D), 2D)));
		s *= EARTH_RADIUS;
		s = Math.round(s * 1000D);
		return s;
	}

	/**
	 * 计算中心经纬度与目标经纬度的距离（米）
	 * 不太准确*
	 *
	 * @param centerLon
	 *            中心精度
	 * @param centerLat
	 *            中心纬度
	 * @param targetLon
	 *            需要计算的精度
	 * @param targetLat
	 *            需要计算的纬度
	 * @return 米
	 */
	@Deprecated
	public static double distance(double centerLon, double centerLat, double targetLon, double targetLat) {

		double jl_jd = 102834.74258026089786013677476285;// 每经度单位米;
		double jl_wd = 111712.69150641055729984301412873;// 每纬度单位米;
		double b = Math.abs((centerLat - targetLat) * jl_jd);
		double a = Math.abs((centerLon - targetLon) * jl_wd);
		return Math.sqrt((a * a + b * b));
	}

	public static void main(String[] args) {
		System.out.println(JSON.toJSON(getScope(113.63069,34.76158,2)));
		System.out.println(distance(113.63069,34.76158,113.65256435859929,34.779550479444154));
		System.out.println(getDistance(34.76158,113.63069,34.779550479444154,113.65256435859929));
		System.out.println(distanceKM(113.63069,34.76158,113.65256435859929,34.779550479444154));
	}

}
